package com.jl.card.parse.part.simpleTLV;

import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Iterator;

import com.jl.card.parse.IAPDUComponent;
import com.jl.card.parse.part.SimpleTLVPart;
import com.jl.card.util.SimpleTLV;
import com.jl.card.util.SimpleTag;
import com.jl.sms.ISMS;
import com.jl.sms.factory.ShortMessage;
import com.jl.util.CodeUtil;
import com.jl.util.HexUtil;

public class SimpleTLVTool {

	private static final String SEP = ",";

	/**
	 * 
	 * @param parent
	 * @param tlv
	 *            a list of simple TLV
	 */
	public static void analyse(IAPDUComponent parent, SimpleTLV tlv) {
		Iterator<SimpleTLV> it = tlv.iterator();
		while (it.hasNext()) {
			SimpleTLV temp = it.next();
			new SimpleTLVPart(parent, temp.toBinary());
		}
	}
	
	public static String getTagName(SimpleTag tag){
		return SimpleTagConstants.getTagName(tag);
	}

	public static String getValueInfo(SimpleTLV tlv) {
		SimpleTag tag = tlv.getTag();
		byte[] value = tlv.valueAsByteArray();
		StringBuilder sb = new StringBuilder();
		if (tag.equals(SimpleTagConstants.TAG_CommandDetail)) {
			sb.append(ProactiveCommand.getCommandName(value[1]));
			sb.append(SEP);
			sb.append(ProactiveCommand.getCommandQualifier(value[1],value[2]));
		}else if (tag.equals(SimpleTagConstants.TAG_DeviceIdentity)) {
			sb.append("Source:").append(DeviceID.getIDName(value[0]));
			sb.append(SEP);
			sb.append("Destination:").append(DeviceID.getIDName(value[1]));
		}else if (tag.equals(SimpleTagConstants.TAG_Result)) {
			sb.append(Result.getResultName(value[0]));
		}else if (tag.equals(SimpleTagConstants.TAG_TextString)) {
			switch (value[0]) {
			case (byte) 0x08://UCS2
				sb.append(new String(value, 1, value.length - 1,
						Charset.forName("UTF-16BE")));
				break;
			case (byte) 0x04://unpacked ASC
				sb.append(new String(value, 1, value.length - 1,
						Charset.forName("US-ASCII")));
				break;
			case (byte) 0x00://packed 7bit
				sb.append(CodeUtil.code7Bit(Arrays.copyOfRange(value, 1, value.length)));
				break;
			default:
				sb.append(new String(value, 0, value.length,
						Charset.forName("US-ASCII")));
				break;
			}
		}else if (tag.equals(SimpleTagConstants.TAG_Item)) {
			sb.append("ID:").append(HexUtil.toHexXX(value[0] & 0xFF));
			sb.append("Text:");
			switch (value[1]) {
			case (byte) 0x80:
				sb.append(new String(value,  2, value.length - 2,
						Charset.forName("UTF-16BE")));
				break;
			case (byte) 0x81:
			case (byte) 0x82:
			case (byte) 0x83:
				break;
			default:
				sb.append(new String(value, 1, value.length - 1,
						Charset.forName("US-ASCII")));
				break;
			}
		}else if (tag.equals(SimpleTagConstants.TAG_ItemIdentifier)) {
			sb.append("ID:").append(HexUtil.toHexXX(value[0] & 0xFF));
		}else if (tag.equals(SimpleTagConstants.TAG_ResponseLength)) {
			sb.append("Min:").append(value[0] & 0xFF);
			sb.append(" ");
			sb.append("Max:").append(value[1] & 0xFF);
		}else if (tag.equals(SimpleTagConstants.TAG_AlphaIdentifier)) {
			switch (value[0]) {
			case (byte) 0x80:
				sb.append(new String(value,  1, value.length - 1,
						Charset.forName("UTF-16BE")));
				break;
			case (byte) 0x81:
			case (byte) 0x82:
			case (byte) 0x83:
				break;
			default:
				sb.append(new String(value, 0, value.length,
						Charset.forName("US-ASCII")));
				break;
			}
		}else if (tag.equals(SimpleTagConstants.TAG_SMSTPDU) || tag.equals(SimpleTagConstants.TAG_CDMASMSTPDU)) {
			ISMS sms = ShortMessage.parse(HexUtil.toHexString(tlv.toBinary()), "");
			if(sms == null){
				sb.append("Parse Short Message Error!!!");
			}else{
				sb.append("Address:").append(sms.getAddress());
				sb.append(" UserData:");
				try {
					sb.append(sms.getUserData().getUserDataAsValue());
				} catch (GeneralSecurityException e) {
					sb.append("The message is eccrypted");
				}
			}
		}else if(tag.equals(SimpleTagConstants.TAG_Address)){
			for(int i = 0; i < value.length; i++){
				if(i == 0){
					if(value[i] == (byte)0x81){
						sb.append("+");
					}
				}else{
					char right = (char) (value[i] & 0x0F | 0x30);
					sb.append(Character.isDigit(right) ? right : "");
					char left = (char) ((value[i] >> 4) & 0x0F | 0x30);
					sb.append(Character.isDigit(left) ? left : "");
				}
			}
		}
		return sb.toString();
	}
}
